import jieba
from pyecharts.charts import Bar, Pie, WordCloud, Line, Page
import os
import pandas as pd
from collections import Counter
from pyecharts.charts import Line
from pyecharts import options as opts
from pyecharts.globals import ThemeType, SymbolType
from pyecharts.options import DataZoomOpts


class VisualizationTool:
    @staticmethod
    def comments_gender_pies(comments):
        # 统计评论者的性别
        gender_counts = {'男': 0, '女': 0, '保密': 0}

        for comment in comments:
            gender = comment.account_sex
            if gender == '男':
                gender_counts['男'] += 1
            elif gender == '女':
                gender_counts['女'] += 1
            else:
                gender_counts['保密'] += 1

        # 生成饼图
        def generate_pie(data, title) -> Pie:
            c = (
                Pie()
                    .add("", [list(z) for z in zip(data.keys(), data.values())])
                    .set_global_opts(
                    title_opts=opts.TitleOpts(title=title),
                    legend_opts=opts.LegendOpts(is_show=False),
                    toolbox_opts=opts.ToolboxOpts(is_show=False)
                )
                    .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {d}%"))
            )
            return c

        pie = generate_pie(gender_counts, title='')

        # 展示饼图
        return pie

    @staticmethod
    def violence_comment_word_cloud(comments):
        # 加载停用词
        stopwords_file = "./static/stopwords/stopwords.txt"
        if os.path.exists(stopwords_file):
            with open(stopwords_file, 'r', encoding='utf-8') as file:
                stopwords = [line.strip() for line in file]
        else:
            stopwords = []

        words = []
        for comment in comments:
            comment_text = comment.content
            seg_list = jieba.cut(comment_text)
            words.extend([word for word in seg_list if word.isalnum() and word not in stopwords])
        word_counts = Counter(words)

        # 绘制词云图
        wordcloud = (
            WordCloud()
                .add(series_name="Violence Comment Word Cloud", data_pair=list(word_counts.items()),
                     word_size_range=[20, 100], shape=SymbolType.DIAMOND)
                .set_global_opts(title_opts=opts.TitleOpts(title="Violence Comment Word Cloud"))
                .set_series_opts(textstyle_opts=opts.TextStyleOpts())
        )
        return wordcloud

    @staticmethod
    def line_for_comment_by_time(comments):
        # 将时间字段转为 DatetimeIndex
        publish_time = pd.to_datetime([c.publish_time for c in comments])
        # 将Comments列表转换为Pandas DataFrame
        df = pd.DataFrame({
            'publish_time': publish_time,
            'is_violent': [int(c.is_violence) for c in comments]
        })
        # 将publish_time设置为DataFrame的索引
        df.set_index('publish_time', inplace=True)

        # 将评论按时间段分组（每30分钟）
        gp = df.groupby(pd.Grouper(freq='30T'))

        # 在每个时间段内聚合评论数据，计算出评论总数和涉及网络暴力的评论数量
        comment_counts = gp['is_violent'].count()
        violent_counts = gp['is_violent'].sum()

        # 定义第一个 Y 轴，即 Total Comments 的坐标轴
        yaxis1_opts = opts.AxisOpts(
            name='Total Comments',  # 设置坐标系名称
            position='left',  # 设置坐标轴位置，可以是 'left', 'right', 'top', 'bottom'
            axisline_opts=opts.AxisLineOpts(  # 设置坐标轴线的样式
                is_on_zero=False,  # 坐标轴不经过原点
                linestyle_opts=opts.LineStyleOpts(color='#235894', width=2)  # 线条颜色为蓝色，线宽为2
            ),
            axislabel_opts=opts.LabelOpts(  # 设置坐标轴标签的样式
                color='#235894',  # 字体颜色为蓝色
                font_size=14,  # 字体大小为14
                formatter='{value}'  # 标签格式化字符串
            ),
            splitline_opts=opts.SplitLineOpts(  # 设置坐标轴分隔线的样式
                is_show=True,  # 显示分隔线
                linestyle_opts=opts.LineStyleOpts(opacity=0.5, width=1)  # 分隔线颜色为透明度为0.5的灰色
            )
        )

        # 定义第二个 Y 轴，即 Violent Comments 的坐标轴
        yaxis2_opts = opts.AxisOpts(
            name='Violent Comments',  # 设置坐标系名称
            position='right',  # 设置坐标轴位置为右侧
            axisline_opts=opts.AxisLineOpts(  # 设置坐标轴线的样式
                is_on_zero=False,  # 坐标轴不经过原点
                linestyle_opts=opts.LineStyleOpts(color='#b0383f', width=2)  # 线条颜色为红色，线宽为2
            ),
            axislabel_opts=opts.LabelOpts(  # 设置坐标轴标签的样式
                color='#b0383f',  # 字体颜色为红色
                font_size=14,  # 字体大小为14
                formatter='{value}'  # 标签格式化字符串
            )
        )

        # 将定义好的 Y 轴样式添加到 'yaxis' 列表中
        yaxis_opts = [yaxis1_opts, yaxis2_opts]

        line = Line()
        time_list = comment_counts.index.to_pydatetime().tolist()
        line.add_xaxis(time_list)

        line.add_yaxis("Total Comments",
                       comment_counts,
                       is_smooth=True,
                       is_symbol_show=True,  # 显示每个点的标记
                       symbol_size=8,  # 标记的大小
                       label_opts=opts.LabelOpts(is_show=False, formatter="{c}"),
                       )
        line.add_yaxis("Violent Comments",
                       violent_counts,
                       is_smooth=True,
                       is_symbol_show=True,  # 显示每个点的标记
                       symbol_size=8,  # 标记的大小
                       label_opts=opts.LabelOpts(is_show=False, formatter="{c}"),
                       )
        line.set_global_opts(
            title_opts=opts.TitleOpts(title="评论增长状态"),
            xaxis_opts=opts.AxisOpts(
                type_="time",
                split_number=12,
                axislabel_opts={
                    "rotate": 15,
                    "font_size": 10
                }
            ),
            toolbox_opts=opts.ToolboxOpts(),
            datazoom_opts=[DataZoomOpts()],
        )
        return line
